import { plainToClass, instanceToPlain } from 'class-transformer';
import {
  Body,
  Controller,
  Req,
  Post,
  Get,
  Query,
  Param,
  Delete,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import {
  ApiOperation,
  ApiResponse,
  ApiTags,
  ApiHeaders,
} from '@nestjs/swagger';

import { UserService } from './user.service';
import { CreateUserDto, LoginUserDto } from './user.schema';
import { Public } from '../../auth/auth.decorator';
import { User } from '../../entity/user.entity';
import { Response } from '../../../infra/schema/response';
import { BcryptService } from '../../../infra/service/bcrypt.service';

@ApiTags('用户')
@Controller('users')
export class UserController {
  constructor(
    private readonly userService: UserService,
    private readonly bcryptService: BcryptService,
    private readonly jwtService: JwtService,
  ) {}

  @Public()
  @Post('register')
  @ApiOperation({ summary: '用户注册' })
  @ApiResponse({ type: Response<string> })
  async userRegister(@Body() createUserDto: CreateUserDto): Promise<Response> {
    if (await this.userService.checkNameExist(createUserDto.username)) {
      return Response.error('用户名已存在');
    }

    createUserDto.password = await this.bcryptService.careatePassword(
      createUserDto.password,
    );

    const user = plainToClass(User, createUserDto, {
      excludePrefixes: ['confirmPassword'],
    });
    await this.userService.createUser(user);
    return Response.success();
  }

  @Public()
  @Post('login')
  @ApiOperation({ summary: '用户登录' })
  @ApiResponse({ type: Response<string> })
  async userLogin(@Body() loginUserDto: LoginUserDto): Promise<Response> {
    const user = await this.userService.getUserByName(loginUserDto.username);
    if (!user) {
      return Response.error('用户不存在');
    }

    if (
      !(await this.bcryptService.checkPassword(
        loginUserDto.password,
        user.password,
      ))
    ) {
      return Response.error('密码错误');
    }

    const payload = instanceToPlain(user, { excludePrefixes: ['password'] });
    const token = this.jwtService.sign(payload);

    const reponse = { user: payload, token: token };
    return Response.success(reponse);
  }

  @Get('info')
  @ApiOperation({ summary: '通过token查询用户信息' })
  @ApiResponse({ type: Response<string> })
  @ApiHeaders([
    {
      name: 'Authorization',
      description: 'Bearer token',
      // required: true,
      schema: {
        type: 'string',
      },
    },
  ])
  async getUserByToken(@Req() Request: any): Promise<any> {
    // console.log(Request.username, '111111111111111111111 2222222');
    const reponse = await this.userService.getUserByName(Request.user.username);
    return Response.success(reponse);
  }

  @Get(':id')
  @ApiOperation({ summary: '通过ID查询用户信息' })
  @ApiResponse({ type: Response<string> })
  async getUser(@Param('id') id: number): Promise<any> {
    const reponse = await this.userService.getUserById(id);
    return Response.success(reponse);
  }

  @Get()
  @ApiOperation({ summary: '查询用户列表' })
  @ApiResponse({ type: [User] })
  async getAllUser(): Promise<Response<User[]>> {
    const users = await this.userService.findAll();
    return Response.success(users);
  }

  @Delete(':id')
  @ApiOperation({ summary: '删除用户' })
  @ApiResponse({ status: 200, description: '用户删除成功' })
  async deleteUser(@Param('id') id: number): Promise<Response<void>> {
    await this.userService.delete(id);
    return Response.success();
  }
}
